namespace PDUConverter
{
    /// <summary>
    /// TP-PI / TP-Parameter-Indicator. Represents particular optional parameter
    /// presence in the fields which follow.
    /// </summary>
    public class ParameterIndicator
    {
        private const byte bit0 = 1;
        private const byte bit1 = 2;
        private const byte bit2 = 4;
        private const byte bit3 = 8;
        private const byte bit4 = 0x10;
        private const byte bit5 = 0x20;
        private const byte bit6 = 0x40;
        private const byte bit7 = 0x80;
        private bool extension;
        private bool reserved_bit3;
        private bool reserved_bit4;
        private bool reserved_bit5;
        private bool reserved_bit6;
        private bool tp_dcs;
        private bool tp_pid;
        private bool tp_udl;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:GsmComm.PduConverter.ParameterIndicator" />.
        /// </summary>
        /// <param name="value">The value to initialize the object with.</param>
        public ParameterIndicator(byte value)
        {
            this.tp_pid = (value & 1) > 0;
            this.tp_dcs = (value & 2) > 0;
            this.tp_udl = (value & 4) > 0;
            this.reserved_bit3 = (value & 8) > 0;
            this.reserved_bit4 = (value & 0x10) > 0;
            this.reserved_bit5 = (value & 0x20) > 0;
            this.reserved_bit6 = (value & 0x40) > 0;
            this.extension = (value & 0x80) > 0;
        }

        /// <summary>
        /// Converts the value of the specified <see cref="T:GsmComm.PduConverter.ParameterIndicator" /> structure into a <see cref="T:System.Byte" />.
        /// </summary>
        /// <param name="pi">A <see cref="T:GsmComm.PduConverter.ParameterIndicator" /> structure.</param>
        /// <returns>A new <see cref="T:System.Byte" /> value representing the <see cref="T:GsmComm.PduConverter.ParameterIndicator" />'s value.</returns>
        public static implicit operator byte(ParameterIndicator pi)
        {
            return pi.ToByte();
        }

        /// <summary>
        /// Converts the the specified <see cref="T:System.Byte" /> value into a <see cref="T:GsmComm.PduConverter.ParameterIndicator" /> structure.
        /// </summary>
        /// <param name="b">A <see cref="T:System.Byte" /> value.</param>
        /// <returns>A new <see cref="T:GsmComm.PduConverter.ParameterIndicator" /> structure representing the <see cref="T:System.Byte" /> value.</returns>
        public static implicit operator ParameterIndicator(byte b)
        {
            return new ParameterIndicator(b);
        }

        /// <summary>
        /// Returns the byte equivalent of this instance.
        /// </summary>
        /// <returns>The byte value.</returns>
        public byte ToByte()
        {
            byte num = 0;
            if (this.tp_pid)
            {
                num = (byte) (num | 1);
            }
            if (this.tp_dcs)
            {
                num = (byte) (num | 2);
            }
            if (this.tp_udl)
            {
                num = (byte) (num | 4);
            }
            if (this.reserved_bit3)
            {
                num = (byte) (num | 8);
            }
            if (this.reserved_bit4)
            {
                num = (byte) (num | 0x10);
            }
            if (this.reserved_bit5)
            {
                num = (byte) (num | 0x20);
            }
            if (this.reserved_bit6)
            {
                num = (byte) (num | 0x40);
            }
            if (this.extension)
            {
                num = (byte) (num | 0x80);
            }
            return num;
        }

        /// <summary>
        /// When set to true, will indicate that another TP-PI octet follows immediately afterwards.
        /// </summary>
        public bool Extension
        {
            get
            {
                return this.extension;
            }
            set
            {
                this.extension = value;
            }
        }

        /// <summary>
        /// Reserved. If set to true, the receiving entity should ignore
        /// this setting.
        /// </summary>
        public bool Reserved_Bit3
        {
            get
            {
                return this.reserved_bit3;
            }
            set
            {
                this.reserved_bit3 = value;
            }
        }

        /// <summary>
        /// Reserved. If set to true, the receiving entity should ignore
        /// this setting.
        /// </summary>
        public bool Reserved_Bit4
        {
            get
            {
                return this.reserved_bit4;
            }
            set
            {
                this.reserved_bit4 = value;
            }
        }

        /// <summary>
        /// Reserved. If set to true, the receiving entity should ignore
        /// this setting.
        /// </summary>
        public bool Reserved_Bit5
        {
            get
            {
                return this.reserved_bit5;
            }
            set
            {
                this.reserved_bit5 = value;
            }
        }

        /// <summary>
        /// Reserved. If set to true, the receiving entity should ignore
        /// this setting.
        /// </summary>
        public bool Reserved_Bit6
        {
            get
            {
                return this.reserved_bit6;
            }
            set
            {
                this.reserved_bit6 = value;
            }
        }

        /// <summary>
        /// When true, a TP-DCS field is present.
        /// </summary>
        public bool TP_DCS
        {
            get
            {
                return this.tp_dcs;
            }
            set
            {
                this.tp_dcs = value;
            }
        }

        /// <summary>
        /// When true, a TP-PID field is present.
        /// </summary>
        public bool TP_PID
        {
            get
            {
                return this.tp_pid;
            }
            set
            {
                this.tp_pid = value;
            }
        }

        /// <summary>
        /// When false, neither TP-UDL nor TP-UD field can be present.
        /// </summary>
        public bool TP_UDL
        {
            get
            {
                return this.tp_udl;
            }
            set
            {
                this.tp_udl = value;
            }
        }
    }
}